<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>音乐播放器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .player-container {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .input-group {
            margin: 20px 0;
        }
        .input-group input {
            width: 100%;
            padding: 10px;
            margin-top: 5px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        .button-group {
            display: flex;
            gap: 10px;
            margin-top: 10px;
        }
        .play-button, .stop-button, .vip-button {
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            color: white;
            font-size: 14px;
        }
        .play-button {
            background-color: #4CAF50;
        }
        .play-button:hover {
            background-color: #45a049;
        }
        .stop-button {
            background-color: #f44336;
        }
        .stop-button:hover {
            background-color: #da190b;
        }
        .status {
            margin-top: 20px;
            padding: 10px;
            border-radius: 4px;
            background-color: #e8f5e9;
            display: none;
        }
        .status.error {
            background-color: #ffebee;
        }
        .volume-control {
            margin-top: 20px;
            padding: 10px;
            border-top: 1px solid #eee;
        }
        .volume-slider {
            width: 100%;
            margin: 10px 0;
        }
        .volume-value {
            text-align: center;
            color: #666;
        }
        .tab-container {
            margin-bottom: 20px;
        }
        .tab-button {
            padding: 10px 20px;
            border: none;
            background: none;
            cursor: pointer;
            font-size: 16px;
            color: #666;
        }
        .tab-button.active {
            color: #4CAF50;
            border-bottom: 2px solid #4CAF50;
        }
        .tab-content {
            display: none;
            padding: 20px 0;
        }
        .tab-content.active {
            display: block;
        }
        .song-list {
            margin-top: 20px;
            max-height: 400px;
            overflow-y: auto;
            border: 1px solid #eee;
            border-radius: 4px;
        }
        .song-item {
            padding: 10px;
            border-bottom: 1px solid #eee;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .song-item:last-child {
            border-bottom: none;
        }
        .song-info {
            flex: 1;
            overflow: hidden;
        }
        .song-title {
            font-weight: bold;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .song-artist {
            font-size: 0.9em;
            color: #666;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .song-item button {
            margin-left: 10px;
        }
        .vip-button {
            background-color: #f44336;
            cursor: not-allowed;
            opacity: 0.7;
        }
        .vip-button:disabled {
            opacity: 0.7;
            cursor: not-allowed;
        }
        .play-button.loading {
            background-color: #FFA726;
        }
        .play-button.loading:hover {
            background-color: #FB8C00;
        }
        .status.loading {
            background-color: #fff3e0;
            animation: pulse 1.5s infinite;
        }
        
        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.7; }
            100% { opacity: 1; }
        }
        .vip-song {
            background-color: rgba(244, 67, 54, 0.05);
        }
        .play-button:disabled {
            opacity: 0.7;
            cursor: wait;
        }
        .duration-button {
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            color: white;
            background-color: #2196F3;
            font-size: 14px;
        }
        .duration-button:hover {
            background-color: #1976D2;
        }
        .duration-button:disabled {
            opacity: 0.7;
            cursor: not-allowed;
        }
        /* 播放控制模块样式 */
        .playback-control {
            margin-top: 20px;
            padding: 15px;
            border-top: 1px solid #eee;
            display: none;
        }
        .playback-control.active {
            display: block;
        }
        .progress-container {
            width: 100%;
            margin: 10px 0;
        }
        .progress-bar {
            width: 100%;
            height: 5px;
            background-color: #ddd;
            border-radius: 5px;
            cursor: pointer;
            position: relative;
        }
        .progress-current {
            height: 100%;
            background-color: #4CAF50;
            border-radius: 5px;
            width: 0%;
            transition: width 0.1s linear;
        }
        .progress-hover {
            position: absolute;
            top: -25px;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 12px;
            display: none;
        }
        .progress-bar:hover .progress-hover {
            display: block;
        }
        .time-display {
            display: flex;
            justify-content: space-between;
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
        .control-buttons {
            display: flex;
            gap: 10px;
            margin-top: 10px;
            align-items: center;
        }
        .control-button {
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            color: white;
            font-size: 14px;
            background-color: #4CAF50;
        }
        .control-button:hover {
            opacity: 0.9;
        }
        .control-button.pause {
            background-color: #FFA000;
        }
    </style>
</head>
<body>
    <div class="player-container">
        <h1>音乐播放器</h1>
        
        <div class="tab-container">
            <button class="tab-button active" onclick="switchTab('stream')">流媒体</button>
            <button class="tab-button" onclick="switchTab('playlist')">网易云歌单</button>
        </div>

        <div id="stream-tab" class="tab-content active">
            <div class="input-group">
                <label for="urlInput">流媒体 URL</label>
                <input type="text" id="urlInput" placeholder="输入流媒体 URL">
            </div>
            <div class="button-group">
                <button class="play-button" onclick="streamPlayer.playStream()">播放</button>
                <button class="stop-button" onclick="streamPlayer.stopStream()">停止</button>
                <button class="duration-button" onclick="streamPlayer.getDuration()">时长</button>
            </div>
            
            <!-- 播放控制模块 -->
            <div id="playbackControl" class="playback-control">
                <div class="progress-container">
                    <div class="progress-bar" id="progressBar">
                        <div class="progress-current" id="progressCurrent"></div>
                        <div class="progress-hover" id="progressHover">00:00</div>
                    </div>
                    <div class="time-display">
                        <span id="currentTime">00:00</span>
                        <span id="totalTime">00:00</span>
                    </div>
                </div>
                <div class="control-buttons">
                    <button class="control-button pause" onclick="streamPlayer.togglePause()">暂停</button>
                </div>
            </div>
        </div>

        <div id="playlist-tab" class="tab-content">
            <div class="input-group">
                <label for="playlistInput">歌单 ID</label>
                <input type="text" id="playlistInput" placeholder="输入网易云歌单ID">
                <button class="play-button" onclick="playlistPlayer.loadPlaylist()">加载歌单</button>
            </div>
            <div class="song-list" id="songList"></div>
            <div class="button-group">
                <button class="stop-button" onclick="playlistPlayer.stopPlaylist()">停止</button>
            </div>
        </div>

        <div class="volume-control">
            <label for="volumeSlider">音量控制</label>
            <input type="range" id="volumeSlider" class="volume-slider" min="0" max="63" step="1">
            <div class="volume-value" id="volumeValue">当前音量: 0</div>
        </div>

        <div id="status" class="status"></div>
    </div>

    <script>
        function switchTab(tabName) {
            // 更新按钮状态
            document.querySelectorAll('.tab-button').forEach(button => {
                button.classList.remove('active');
            });
            document.querySelector(`[onclick="switchTab('${tabName}')"]`).classList.add('active');

            // 更新内容显示
            document.querySelectorAll('.tab-content').forEach(content => {
                content.classList.remove('active');
            });
            document.getElementById(`${tabName}-tab`).classList.add('active');
        }

        const streamPlayer = {
            isPlaying: false,
            isPaused: false,
            currentPosition: 0,
            totalDuration: 0,
            progressInterval: null,
            startTime: null,
            currentUrl: null,

            formatTime: function(seconds) {
                const mins = Math.floor(seconds / 60);
                const secs = Math.floor(seconds % 60);
                return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
            },

            updateProgress: function() {
                if (!this.isPlaying || this.isPaused) return;
                
                const now = Date.now();
                const elapsed = (now - this.startTime) / 1000;
                const currentTime = this.currentPosition + elapsed;
                
                document.getElementById('currentTime').textContent = this.formatTime(currentTime);
                
                if (this.totalDuration > 0) {
                    const progress = (currentTime / this.totalDuration) * 100;
                    document.getElementById('progressCurrent').style.width = `${Math.min(progress, 100)}%`;
                }
            },

            startProgressTracking: function() {
                this.progressInterval = setInterval(() => this.updateProgress(), 100);
            },

            stopProgressTracking: function() {
                if (this.progressInterval) {
                    clearInterval(this.progressInterval);
                    this.progressInterval = null;
                }
            },

            playStream: async function() {
                const url = document.getElementById('urlInput').value;
                if (!url) {
                    showStatus('请输入有效的 URL', true);
                    return;
                }

                try {
                    // 如果正在播放，先停止
                    if (this.isPlaying) {
                        await this.stopStream();
                    }

                    // 开始播放并获取时长信息
                    const response = await fetch('/api/music/stream', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ url }),
                    });

                    const data = await response.json();
                    if (!response.ok) {
                        throw new Error(data.error || '播放失败');
                    }

                    if (!data.duration) {
                        throw new Error('无法获取时长信息');
                    }

                    // 设置时长信息
                    const duration = data.duration;
                    this.totalDuration = duration.TotalSeconds;
                    document.getElementById('totalTime').textContent = 
                        `${String(duration.Minutes).padStart(2, '0')}:${String(duration.Seconds).padStart(2, '0')}`;

                    this.isPlaying = true;
                    this.isPaused = false;
                    this.startTime = Date.now();
                    this.currentUrl = url;
                    this.currentPosition = 0;
                    this.startProgressTracking();
                    
                    document.getElementById('playbackControl').classList.add('active');
                    document.querySelector('.control-button.pause').textContent = '暂停';
                    showStatus(`正在播放: ${url}`);
                } catch (error) {
                    showStatus(error.message, true);
                }
            },

            stopStream: async function() {
                try {
                    const response = await fetch('/api/music/stop', {
                        method: 'POST'
                    });

                    if (!response.ok) {
                        throw new Error('停止播放失败');
                    }

                    this.isPlaying = false;
                    this.isPaused = false;
                    this.currentPosition = 0;
                    this.currentUrl = null;
                    this.stopProgressTracking();
                    document.getElementById('playbackControl').classList.remove('active');
                    document.getElementById('progressCurrent').style.width = '0%';
                    document.getElementById('currentTime').textContent = '00:00';
                    showStatus('已停止播放');
                } catch (error) {
                    showStatus('停止播放失败: ' + error.message, true);
                }
            },

            togglePause: async function() {
                if (!this.isPlaying) return;

                try {
                    const endpoint = this.isPaused ? '/api/music/resume' : '/api/music/pause';
                    const response = await fetch(endpoint, {
                        method: 'POST'
                    });

                    if (!response.ok) {
                        throw new Error(this.isPaused ? '继续播放失败' : '暂停播放失败');
                    }

                    this.isPaused = !this.isPaused;
                    if (this.isPaused) {
                        // 暂停时，记录当前播放位置
                        const elapsed = (Date.now() - this.startTime) / 1000;
                        this.currentPosition += elapsed;
                        this.stopProgressTracking();
                        document.querySelector('.control-button.pause').textContent = '继续';
                    } else {
                        // 继续播放时，重置开始时间
                        this.startTime = Date.now();
                        this.startProgressTracking();
                        document.querySelector('.control-button.pause').textContent = '暂停';
                    }
                } catch (error) {
                    showStatus(error.message, true);
                }
            },

            seekTo: async function(position) {
                if (!this.isPlaying) return;
                
                try {
                    const response = await fetch('/api/music/seek', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ position }),
                    });

                    if (!response.ok) {
                        throw new Error('跳转失败');
                    }

                    // 更新播放状态
                    this.currentPosition = position;
                    this.startTime = Date.now();
                    
                    // 如果当前是暂停状态，重新开始播放
                    if (this.isPaused) {
                        this.isPaused = false;
                        this.startProgressTracking();
                        document.querySelector('.control-button.pause').textContent = '暂停';
                    }
                } catch (error) {
                    showStatus('跳转失败: ' + error.message, true);
                }
            },

            getDuration: async function() {
                const url = document.getElementById('urlInput').value;
                if (!url) {
                    showStatus('请输入有效的 URL', true);
                    return;
                }

                try {
                    showStatus('正在获取音频时长...', false, true);
                    const response = await fetch('/api/music/stream', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ url }),
                    });
                    
                    const data = await response.json();
                    if (!response.ok) {
                        throw new Error(data.error || '获取时长失败');
                    }

                    if (!data.duration) {
                        throw new Error('无法获取时长信息');
                    }

                    const duration = data.duration;
                    showStatus(`音频时长: ${String(duration.Minutes).padStart(2, '0')}:${String(duration.Seconds).padStart(2, '0')}`);
                } catch (error) {
                    showStatus(error.message, true);
                }
            }
        };

        const playlistPlayer = {
            currentSongs: [],
            currentPage: 1,
            pageSize: 20,
            isLoading: false,
            hasMore: true,

            displaySongs: function() {
                const songList = document.getElementById('songList');
                songList.innerHTML = this.currentSongs.map((song, index) => `
                    <div class="song-item ${song.fee === 1 ? 'vip-song' : ''}">
                        <div class="song-info">
                            <div class="song-title">${song.name}</div>
                            <div class="song-artist">${song.artists.join('/')}</div>
                        </div>
                        ${this.getPlayButton(song, index)}
                    </div>
                `).join('');
            },

            getPlayButton: function(song, index) {
                if (song.fee === 1) {
                    return `<button class="vip-button" disabled title="VIP 专属歌曲">VIP</button>`;
                }
                if (song.url) {
                    return `<button class="play-button" onclick="playlistPlayer.playSong(${index})">播放</button>`;
                }
                return `<button class="play-button loading" onclick="playlistPlayer.playSong(${index})" title="点击获取播放地址">获取</button>`;
            },

            loadPlaylist: async function() {
                const playlistId = document.getElementById('playlistInput').value;
                if (!playlistId) {
                    showStatus('请输入歌单ID', true);
                    return;
                }

                try {
                    showStatus('正在加载歌单...', false, true);
                    this.currentPage = 1;
                    this.currentSongs = [];
                    this.hasMore = true;
                    await this.loadMoreSongs(playlistId);
                } catch (error) {
                    showStatus('加载歌单失败: ' + error.message, true);
                }
            },

            loadMoreSongs: async function(playlistId) {
                if (this.isLoading || !this.hasMore) return;

                this.isLoading = true;
                try {
                    const response = await fetch(`/api/playlist/detail?id=${playlistId}&page=${this.currentPage}&pageSize=${this.pageSize}`);
                    if (!response.ok) {
                        throw new Error('加载歌单失败');
                    }

                    const result = await response.json();
                    if (!result.songs || result.songs.length === 0) {
                        this.hasMore = false;
                        if (this.currentPage === 1) {
                            throw new Error('歌单为空或无法访问');
                        }
                        return;
                    }

                    this.currentSongs = [...this.currentSongs, ...result.songs];
                    this.displaySongs();
                    
                    // 统计可播放和 VIP 歌曲数量
                    const playableSongs = this.currentSongs.filter(s => s.url).length;
                    const vipSongs = this.currentSongs.filter(s => s.fee === 1).length;
                    const pendingSongs = this.currentSongs.filter(s => !s.url && s.fee !== 1).length;
                    
                    let status = `已加载 ${this.currentSongs.length} 首歌`;
                    if (playableSongs) status += `，${playableSongs} 首可播放`;
                    if (vipSongs) status += `，${vipSongs} 首VIP`;
                    if (pendingSongs) status += `，${pendingSongs} 首待获取`;
                    
                    showStatus(status, false, false);
                    
                    this.currentPage++;
                } catch (error) {
                    showStatus('加载更多歌曲失败: ' + error.message, true);
                } finally {
                    this.isLoading = false;
                }
            },

            // 添加滚动加载
            initScrollLoad: function() {
                const songList = document.getElementById('songList');
                songList.addEventListener('scroll', () => {
                    if (songList.scrollHeight - songList.scrollTop <= songList.clientHeight + 100) {
                        const playlistId = document.getElementById('playlistInput').value;
                        this.loadMoreSongs(playlistId);
                    }
                });
            },

            playSong: async function(index) {
                const song = this.currentSongs[index];
                if (!song) {
                    showStatus('无效的歌曲', true);
                    return;
                }

                if (song.fee === 1) {
                    showStatus('无法播放：VIP 专属歌曲', true);
                    return;
                }

                try {
                    showStatus(`正在获取歌曲信息...`, false, true);
                    
                    // 如果没有 URL，尝试从服务器获取
                    let url = song.url;
                    if (!url) {
                        const response = await fetch('/api/playlist/play', {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                            },
                            body: JSON.stringify({
                                song_id: song.id
                            }),
                        });

                        if (!response.ok) {
                            throw new Error('获取歌曲信息失败');
                        }

                        const result = await response.json();
                        if (!result.url) {
                            throw new Error('无法获取播放地址');
                        }
                        url = result.url;
                        
                        // 更新歌曲 URL 并刷新显示
                        this.currentSongs[index].url = url;
                        this.displaySongs();
                    }

                    // 播放歌曲
                    const playResponse = await fetch('/api/music/stream', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ url: url }),
                    });

                    const data = await playResponse.json();
                    if (!playResponse.ok) {
                        throw new Error(data.error || '播放失败');
                    }

                    if (!data.duration) {
                        throw new Error('无法获取时长信息');
                    }

                    // 设置时长信息
                    const duration = data.duration;
                    streamPlayer.totalDuration = duration.TotalSeconds;
                    document.getElementById('totalTime').textContent = 
                        `${String(duration.Minutes).padStart(2, '0')}:${String(duration.Seconds).padStart(2, '0')}`;

                    // 更新播放控制界面
                    document.getElementById('playbackControl').classList.add('active');
                    streamPlayer.isPlaying = true;
                    streamPlayer.isPaused = false;
                    streamPlayer.startTime = Date.now();
                    streamPlayer.currentPosition = 0;
                    streamPlayer.startProgressTracking();
                    document.querySelector('.control-button.pause').textContent = '暂停';

                    showStatus(`正在播放: ${song.name} - ${song.artists.join('/')}`);
                } catch (error) {
                    showStatus(error.message, true);
                }
            },

            stopPlaylist: function() {
                streamPlayer.stopStream();
            }
        };

        function showStatus(message, isError = false, loading = false) {
            const status = document.getElementById('status');
            status.textContent = message + (loading ? '...' : '');
            status.style.display = 'block';
            status.className = 'status' + (isError ? ' error' : '') + (loading ? ' loading' : '');
            
            if (!loading) {
                setTimeout(() => {
                    status.style.display = 'none';
                }, 5000);
            }
        }

        // 音量控制相关函数
        const volumeControl = {
            init: async function() {
                try {
                    const response = await fetch('/api/volume/get');
                    if (!response.ok) {
                        throw new Error('获取音量失败');
                    }
                    const data = await response.json();
                    const volume = parseInt(data.volume);
                    
                    const slider = document.getElementById('volumeSlider');
                    const volumeValue = document.getElementById('volumeValue');
                    
                    slider.value = volume;
                    volumeValue.textContent = `当前音量: ${volume}`;
                } catch (error) {
                    console.error('初始化音量失败:', error);
                }
            },

            setVolume: async function(volume) {
                try {
                    const response = await fetch('/api/volume/set', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ volume: volume.toString() }),
                    });

                    if (!response.ok) {
                        throw new Error('设置音量失败');
                    }

                    document.getElementById('volumeValue').textContent = `当前音量: ${volume}`;
                } catch (error) {
                    console.error('设置音量失败:', error);
                }
            }
        };

        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            volumeControl.init();

            const slider = document.getElementById('volumeSlider');
            let timeoutId = null;

            slider.addEventListener('input', function() {
                document.getElementById('volumeValue').textContent = `当前音量: ${this.value}`;
            });

            slider.addEventListener('change', function() {
                if (timeoutId) {
                    clearTimeout(timeoutId);
                }
                
                timeoutId = setTimeout(() => {
                    volumeControl.setVolume(this.value);
                }, 100);
            });

            // 从 localStorage 恢复上次的输入
            const lastUrl = localStorage.getItem('lastStreamUrl');
            if (lastUrl) {
                document.getElementById('urlInput').value = lastUrl;
            }

            const lastPlaylistId = localStorage.getItem('lastPlaylistId');
            if (lastPlaylistId) {
                document.getElementById('playlistInput').value = lastPlaylistId;
            }

            // 保存输入到 localStorage
            document.getElementById('urlInput').addEventListener('change', function() {
                localStorage.setItem('lastStreamUrl', this.value);
            });

            document.getElementById('playlistInput').addEventListener('change', function() {
                localStorage.setItem('lastPlaylistId', this.value);
            });

            playlistPlayer.initScrollLoad();

            // 进度条事件处理
            const progressBar = document.getElementById('progressBar');
            const progressHover = document.getElementById('progressHover');

            // 鼠标移动时显示时间
            progressBar.addEventListener('mousemove', function(e) {
                const rect = this.getBoundingClientRect();
                const position = (e.clientX - rect.left) / rect.width;
                const time = position * streamPlayer.totalDuration;
                progressHover.textContent = streamPlayer.formatTime(time);
                progressHover.style.left = `${e.clientX - rect.left}px`;
            });

            // 点击跳转
            progressBar.addEventListener('click', function(e) {
                if (!streamPlayer.isPlaying) return;
                
                const rect = this.getBoundingClientRect();
                const position = (e.clientX - rect.left) / rect.width;
                const newPosition = position * streamPlayer.totalDuration;
                streamPlayer.seekTo(newPosition);
            });
        });
    </script>
</body>
</html> 